local skynet = require "skynet"
local crypt = require "skynet.crypt"
local md5 =	require	"md5"
local web_interface = require "web.web_interface"
local urllib = require "http.url"
local sweb = {}
local typeclass = {}


local function strsplit(pattern, text)
    local list, pos = {}, 1;

    assert(pattern ~= "", "delimiter matches empty string!");

    while true do
        local first, last, match = text:find(pattern, pos);
        if first then -- found?
            list[#list+1] = text:sub(pos, first-1);
            pos = last+1;
        else
            list[#list+1] = text:sub(pos);
            break;
        end
    end

    return list;
end


-- 删除table中的元素  
function removeElementByKey(tbl,key)  
    --新建一个临时的table  
    local tmp ={}  
  
    --把每个key做一个下标，保存到临时的table中，转换成{1=a,2=c,3=b}   
    --组成一个有顺序的table，才能在while循环准备时使用#table  
    for i in pairs(tbl) do  
        table.insert(tmp,i)  
    end  
  
    local newTbl = {}  
    --使用while循环剔除不需要的元素  
    local i = 1  
    while i <= #tmp do  
        local val = tmp [i]  
        if val == key then  
            --如果是需要剔除则remove   
            table.remove(tmp,i)  
         else  
            --如果不是剔除，放入新的tabl中  
            newTbl[val] = tbl[val]  
            i = i + 1  
         end  
     end  
    return newTbl  
end


function sweb.interface(name,web_root)
    local G ={}
    local k,v 
    for k,v in pairs(_ENV) do
        G[k] = v
    end
    if typeclass[name] then
      return true,typeclass[name]
    end

    local si,err = web_interface(name,G,nil,web_root)

    if si then
        local ret = {
          rep = {},
          system = {}
        }

        for _,v in ipairs(si) do
          local id, group, name, f = table.unpack(v)
          ret[group][name] = f
        end

        typeclass[name] = ret
        return true, ret
    else
        return false,err
    end
end

function sweb.middle_ware(url,method, header, body,web_root,middle_ware)
    local path, query = urllib.parse(url)   
    local q = {}
    if query then
        q = urllib.parse_query(query)
    end
    local path, query = urllib.parse(url)
    path = strsplit("/",middle_ware)
    local f = path[#path]
    table.remove(path,#path)

    local name = table.concat(path,"/")

    skynet.error("sweb.handle name ",name,"f",f)

    local ok,ret = sweb.interface(name,web_root)
    if not ok then
        return 503,url .." error:no middleware "..ret
    end
    local req = {method = method,header=header,body=body,query=q}
    if ret["rep"][f] then
        local state,retf,fmt = ret["rep"][f](req)
        skynet.error("\n",name.."/"..f,retf)
        if fmt == "base64" then
            retf = crypt.base64encode(retf)
        end
        return state,retf
    else
        return 503,url .." :has no valid handle"
    end
end

function sweb.handle(url,method, header, body,web_root)
    local path, query = urllib.parse(url)   
    path = strsplit("/",path)
    -- skynet.error("path ",#path,path[2])

    local q = {}
    if query then
        q = urllib.parse_query(query)
        local gameKey = "91f77fe1c709a32d065d7e9d9d55f450"

        local sign = q["sign"]
        local content = q["content"]
        if content ~= nil then
            if sign == md5.sumhexa(content .. gameKey) then
                content = crypt.base64decode(content)
                skynet.error("sweb.handle content ",content)
                q = urllib.parse_query(content)
            else
                return 503,url .." sign error"
            end
        elseif q["gnosign"] ~= "1" then
            return 503,url .." format error"
        end
 
    end
    -- local path, query = urllib.parse(url)
    local f = path[#path]
    table.remove(path,#path)
    
    local name = table.concat(path,"/")

    skynet.error("sweb.handle name ",name,"f",f)

    local ok,ret = sweb.interface(name,web_root)
    if not ok then
        skynet.error("sweb.handle error ",ok,ret)
        return 503,url .." error:"..ret
    end
    local req = {query=q}
    if ret["rep"][f] then
        local state,retf,fmt = ret["rep"][f](req)
        skynet.error("\n",name.."/"..f,retf)
        if fmt == "base64" then
            retf = crypt.base64encode(retf)
        end
        return state,retf
    else
        skynet.error("sweb.handle error has no valid handle ")
        return 503,url .." :has no valid handle"
    end
end


return sweb
